---------------------------------------------------------------
File name   :  vv_ahblite_master_sequence_h.e
Title       :  Sequence interface for active master agents
Project     :  vv_ahblite eVC
Developers  :  stefan,filip
Created     :  27.07.2011.
Description :  This file declares the sequence interface of the master.
Notes       :  Only active master agents have a sequence interface.
---------------------------------------------------------------
Copyright  (c)2011
---------------------------------------------------------------

<'
package vv_ahblite;

-- This struct is the generic sequence for the master agent
-- sequence interface.
sequence vv_ahblite_master_sequence using 
    item = MASTER vv_ahblite_transaction,
    created_driver = vv_ahblite_master_driver_u,
    created_kind = vv_ahblite_master_sequence_kind_t;

extend vv_ahblite_master_driver_u {
    p_env : vv_ahblite_env;
    env_name : vv_ahblite_env_name_t;
    p_master : vv_ahblite_master;
    -- This field is automatically constrained by the UVC. It should not be constrained by the user.
    master_name : vv_ahblite_agent_name_t;
    -- Monitor reference
    !p_bus_monitor  : vv_ahblite_bus_monitor;
    
}; 

extend vv_ahblite_master_sequence {

    master_name : vv_ahblite_agent_name_t;
        keep master_name == read_only(driver.master_name);

    -- This is a utility field for basic sequences. This enables
    -- "do master_transaction ...".
    !my_transaction: MASTER vv_ahblite_transaction;

    --IDLE transfer to selected address
    idle(addr : vv_ahblite_addr_t, data_size : vv_ahblite_data_size_t)@driver.clock is {  	
    	do my_transaction keeping {
            .addr == addr;
            .burst == SINGLE;
            .lock == 0;
            .protect == 0x3;
            .data_size == data_size;
            .transfer == IDLE;
            .write_op == 0;
            --.transaction_kind == MASTER;
        };
 	
    };
    --BUSY transfer
    busy(addr : vv_ahblite_addr_t, 
        burst: vv_ahblite_burst_t, 
        size: vv_ahblite_data_size_t,
        write_op: bit)@driver.clock is {  	
    	do my_transaction keeping {
            .addr == addr;
            .burst == burst;
            .lock == 0;
            .protect == 0x3;
            .data_size == size;
            .transfer == BUSY;
            .write_op == write_op;
            --.transaction_kind == MASTER;
        };
    };
        
    --single write method performs a single write transaction with given parameters
    --@addr
    --@data
    --@burst mode
    --@transfer mode
    --@size of transfer
    single_write(addr : vv_ahblite_addr_t, 
        data : list of byte, 
        burst: vv_ahblite_burst_t, 
        transfer: vv_ahblite_transfer_t, 
        size: vv_ahblite_data_size_t) @driver.clock is {
        
        do my_transaction keeping {
            .addr == addr;
            .write_data == data;
            .burst == burst;
            .lock == 0;
            .protect == 0x3;
            .data_size == size;
            .transfer == transfer;
            .write_op == 1;
            .transaction_kind == MASTER;
        };
        
    };
    --single read method performs a single read transaction with given parameters and returns the data
    --@addr
    --@burst mode
    --@transfer mode
    --@size of transfer
    single_read(addr : vv_ahblite_addr_t, 
        burst: vv_ahblite_burst_t, 
        transfer: vv_ahblite_transfer_t, 
        size: vv_ahblite_data_size_t):list of byte @driver.clock is {
        
        do my_transaction keeping {
            .addr == addr;
            .burst == burst;
            .lock == 0;
            .protect == 0x3;
            .data_size == size;
            .transfer == transfer;
            .write_op == 0;
            .transaction_kind == MASTER;
        };
        
        
        
        if my_transaction != NULL {
                result = my_transaction.read_data;
        } else {
               message(MEDIUM,"transaction is NULL");
        };
        
    };
    
    incr4(addr : vv_ahblite_addr_t,
        data : list of vv_ahblite_data_t,
        data_size: vv_ahblite_data_size_t, 
        write : bit) @driver.clock is {
          
        var address : uint (bits : 32);
        address  = addr;
        
        var wdata: list of byte;
        gen wdata keeping {
        	data_size == BYTE => .size() == 1;
        	data_size == HALFWORD => .size() == 2;
        	data_size == WORD => .size() == 4;
        };
        if write == 1 {unpack(packing.low,data[0],wdata);};  
        
        do my_transaction keeping {
            .addr == address;
            .burst == INCR4;
            .lock == 0;
            .protect == 0x3;
            .data_size == data_size;
            .transfer == NONSEQ;
            .write_op == write;
            write ==1  => .write_data == wdata; 
            .transaction_kind == MASTER;
        }; -- first transfer in a burst
            
        var offset: uint (bits:32) = 1;       
        if data_size == HALFWORD { offset <<=1 ;}
        else if data_size == WORD { offset <<=2;}; 
            
        for i from 1 to 3 do {
            address += offset;
            if write == 1 {unpack(packing.low,data[i],wdata);};
            do my_transaction keeping {
                .addr == address;
                .burst == INCR4;
                .lock == 0;
                .protect == 0x3;
                .data_size == data_size;
                .transfer == SEQ;
                .write_op == write;
           		write ==1  => .write_data == wdata; 
                .transaction_kind == MASTER;
            };

          };

     };
        
     incr8(addr : vv_ahblite_addr_t,
        data : list of vv_ahblite_data_t,
        data_size: vv_ahblite_data_size_t, 
        write : bit) @driver.clock is {
          
        var address : uint (bits : 32);
        address  = addr;
        
        var wdata: list of byte;
        gen wdata keeping {
        	data_size == BYTE => .size() == 1;
        	data_size == HALFWORD => .size() == 2;
        	data_size == WORD => .size() == 4;
        };
        if write == 1 {unpack(packing.low,data[0],wdata);};
        
        do my_transaction keeping {
        	
            .addr == address;
            .burst == INCR8;
            .lock == 0;
            .protect == 0x3;
            .data_size == data_size;
            .transfer == NONSEQ;
            .write_op == write;
            write ==1  => .write_data == wdata; 
            .transaction_kind == MASTER;
        }; -- first transfer in a burst
            
        var offset: uint (bits:32) = 1;     
        if data_size == HALFWORD { offset <<=1 ;}
        else if data_size == WORD { offset <<=2;}; 
            
        for i from 1 to 7 do {
            address += offset;
            if write == 1 {unpack(packing.low,data[i],wdata);};
            do my_transaction keeping {
                .addr == address;
                .burst == INCR8;
                .lock == 0;
                .protect == 0x3;
                .data_size == data_size;
                .transfer == SEQ;
                .write_op == write;
                write ==1  => .write_data == wdata; 
                .transaction_kind == MASTER;
            };

          };

     };
    

    busy_transfer(addr: vv_ahblite_addr_t, data_size: vv_ahblite_data_size_t,
          write: bit,length: int, burst: vv_ahblite_burst_t) is empty;

    idle_transfer() is empty;
 
}; 

extend MAIN vv_ahblite_master_sequence {
    
    -- If this field is true (the default), then an objection to TEST_DONE
    -- is raised for the duration of the MAIN sequence. If this field is
    -- false then the MAIN sequence does not contribute to the determination
    -- of end-of-test.
    prevent_test_done : bool;
        keep soft prevent_test_done == TRUE;
    
   -- This field controls the delay between the end of the MAIN sequence
    -- and the dropping of the objection to TEST_DONE (that is, the time
    -- allowed for the last data to drain through the DUT). This is
    -- measured in clock cycles. The default value is 10 clock cycles.
    drain_time : uint;
        keep soft drain_time == 10;

}; 

'>
